home *** CD-ROM | disk | FTP | other *** search
- #include <exec/types.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <assert.h>
- #include <proto/dos.h>
- #include <setjmp.h>
- #include <internal/messages.h>
- #include "config.h"
- #include "lisp.h"
- #include "buffer.h"
- #include "regex.h"
- #include "amiga.h"
- #include "dispextern.h"
- #include "termchar.h"
- #include "paths.h"
- #include "frame.h"
-
- #ifdef USE_PROTOS
- #include "protos.h"
- #endif
-
- #define RANGE(ptr, s, e) ((char *)ptr >= (char *)s && (char *)ptr < (char *)e)
- #define HUNK_POS (VALBITS - 3)
- #define HUNK_MASK (7 << HUNK_POS)
- #define HUNK_CODE (0 << HUNK_POS)
- #define HUNK_DATA (1 << HUNK_POS)
- #define HUNK_BSS (2 << HUNK_POS)
- #define HUNK_MALLOC (3 << HUNK_POS)
- #define HUNK_PURE (4 << HUNK_POS)
- #define ARRAY_MARK_FLAG ((MARKBIT >> 1) & ~MARKBIT)
-
- void *far first_fn = first_function, *far last_fn = last_function;
-
- /* alloc.c */
- extern int *pure, puresize;
- extern struct gcpro *gcprolist;
- extern Lisp_Object *staticvec[];
- extern int staticidx;
- extern struct cons_block *cons_block;
- extern struct Lisp_Cons *cons_free_list;
- extern struct Lisp_Vector *all_vectors;
- extern struct symbol_block *symbol_block;
- extern struct Lisp_Symbol *symbol_free_list;
- extern struct marker_block *marker_block;
- extern struct Lisp_Marker *marker_free_list;
- extern struct interval_block *interval_block;
- extern INTERVAL interval_free_list;
- struct string_block_head
- {
- struct string_block_head *next, *prev;
- int pos;
- };
- struct string_block
- {
- struct string_block *next, *prev;
- #if 0 /* not needed */
- int pos;
- char chars[STRING_BLOCK_SIZE];
- #endif
- };
- extern struct string_block *current_string_block;
- extern struct string_block *first_string_block;
- extern struct string_block *large_string_blocks;
- #ifdef LISP_FLOAT_TYPE
- extern struct float_block *float_block;
- extern struct Lisp_Float *float_free_list;
- #endif /* LISP_FLOAT_TYPE */
-
- struct backtrace /* see eval.c or alloc.c */
- {
- struct backtrace *next;
- Lisp_Object *function;
- Lisp_Object *args; /* Points to vector of args. */
- int nargs; /* Length of vector.
- If nargs is UNEVALLED, args points to slot holding
- list of unevalled args */
- char evalargs;
- /* Nonzero means call value of debugger when done with this operation. */
- char debug_on_exit;
- };
- extern struct backtrace *backtrace_list;
- struct catchtag
- {
- Lisp_Object tag;
- Lisp_Object val;
- struct catchtag *next;
- struct gcpro *gcpro;
- jmp_buf jmp;
- struct backtrace *backlist;
- struct handler *handlerlist;
- int lisp_eval_depth;
- int pdlcount;
- int poll_suppress_count;
- };
- extern struct catchtag *catchlist;
- extern char *stack_copy;
-
- extern int *kbd_macro_buffer;
- extern char *read_buffer, *chars_wasted, *copybuf;
- extern struct minibuf_save_data *minibuf_save_vector;
- extern struct re_pattern_buffer searchbuf;
- #if 0 /* CHFIXME */
- extern int *ILcost, *DLcost, *ILncost, *DLncost;
- #endif
- #if 0
- extern Lisp_Object MouseMap, global_map, Vglobal_map, Vesc_map, Vctl_x_map;
- #else
- extern Lisp_Object global_map, meta_map, control_x_map;
- #endif
- extern Lisp_Object selected_window;
-
- extern char *callint_argfuns[];
-
- /* lread.c/init_obarray variables */
- extern Lisp_Object Qvariable_documentation, Vpurify_flag;
-
- /* eval.c/init_eval_once variables */
- /* specpdl */
-
- /* syntax.c/init_syntax_once */
- /* */
-
- /* window.c variables */
- /* */
-
-
- /* buffer.c */
- /* -> buffer.h */
-
- /* dired.c */
- extern Lisp_Object Qdirectory_files, Qfile_name_completion,
- Qfile_name_all_completions, Qfile_attributes;
-
- /* fileio.c */
- extern Lisp_Object Qset_visited_file_modtime;
-
- /* process.c */
- /* extern Lisp_Object stream_process; CHFIXME activate HAVE_SOCKETS ?*/
-
- /* editfns.c */
- extern char *message_text;
-
- /* regex variables */
- typedef unsigned char *fail_stack_elt_t;
- typedef struct
- {
- fail_stack_elt_t *stack;
- unsigned size;
- unsigned avail; /* Offset of next open position. */
- } fail_stack_type;
- typedef short register_info_type;
-
- extern fail_stack_type fail_stack;
- extern const char ** regstart, ** regend;
- extern const char ** old_regstart, ** old_regend;
- extern const char **best_regstart, **best_regend;
- extern register_info_type *reg_info;
- extern const char **reg_dummy;
- extern void *reg_info_dummy;
-
- /* keyboard.c/variables CHFIXME: need to be checked on version change */
- #define HEAD_TABLE_SIZE 3
- #define SCROLL_BAR_PARTS_SIZE 3
- struct event_head {
- Lisp_Object *var;
- char *name;
- Lisp_Object *kind;
- };
-
- extern struct event_head head_table[];
- extern Lisp_Object *scroll_bar_parts[];
- extern struct input_event *kbd_fetch_ptr;
- extern struct input_event volatile *kbd_store_ptr;
-
- /* search.c */
- extern struct re_registers search_regs;
-
- #if 0
- #define DBUG /* dump debug */
- #endif
-
- static char *dump_error_example[] =
- {
- "dump-error-example-1",
- "dump-error-example-2"
- };
-
- static void cpr() {} /* CHFIXME */
-
- static void *dump_malloc(int size)
- {
- void *new = malloc(size);
-
- if (!new) no_memory();
-
- return new;
- }
-
- static void bailout(char *fn)
- {
- if (fn) _message("%s isn't a dump file for this version of Emacs, aborting", fn);
- else _message("Dump file isn't for this version of Emacs, aborting");
-
- /* We are in deep trouble, as all our variables are potentially corrupt */
- /* Therefore, no cleanup is possible */
- /* Remove cleanup routines */
- onexit(0);
- /* However, the library & the memory allocation should be ok, so
- we can exit reasonably */
- _fail("Some system resources may have been lost");
- }
-
- void print_ranges()
- {
- #if 0
- _message("HUNK_CODE : %08lx .. %08lx (%08lx)",
- first_fn, last_fn, (char *) last_fn - (char *) first_fn);
- _message("HUNK_DATA : %08lx .. %08lx (%08lx)",
- &first_data, &last_data, (char *) &last_data - (char *) &first_data);
- _message("HUNK_BSS : %08lx .. %08lx (%08lx)",
- &first_bss, &last_bss, (char *) &last_bss - (char *) &first_bss);
- _message("HUNK_PURE : %08lx .. %08lx (%08lx)"
- , pure, (char *)pure + puresize, puresize);
- _message("HUNK_MALLOC: %08lx .. %08lx (%08lx)",
- malloc_hunk, malloc_hunk + malloc_hunk_size, malloc_hunk_size);
- #endif
- }
-
- /*
- * ignore:
- * stack_bottom, IconBase, last_marked (array), interval_block_index (int)
- * gcprolist (currently?),
- * pending (list), returned (list)
- */
-
- int
- check_ignore(void *x)
- {
- #ifndef USE_PROTOS
- extern int IconBase, IFFParseBase, interval_block_index, instream, cliphook;
- #else
- extern int interval_block_index;
- #endif
-
- int ign = 0;
- if((x == (void *) &IconBase)
- || (x == (void *) &stack_bottom)
- /* || (x == (void *) &interval_block_index) */
- || (x == (void *) &pure)
- || (x == (void *) &gcprolist)
- || (x == (void *) &malloc_hunk)
- || (x == (void *) &IFFParseBase)
- || (x == (void *) &instream)
- || (x == (void *) &cbuffer_pos)
- || (x == (void *) &cliphook)
- || (x == (void *) ((int *)&cliphook+1))
- || (x == (void *) ((int *)&cliphook+2))
- || (x == (void *) &specpdl_ptr)
- || (x == (void *) &handlerlist) /* CHFIXME: ok? */
- || (x == (void *) &catchlist) /* CHFIXME: ok? */
- || (x == (void *) &backtrace_list) /* CHFIXME: ok? */
- )
- ign = 1;
-
- return ign;
- }
-
- /*
- * test for candidates which may need extra handling on dump
- */
- void
- check_cand(char *s, void *start, void *end)
- {
- unsigned int *ip, *starthit = NULL, *lasthit = NULL;
- unsigned short int *is;
- int range = 0;
- int de = ((unsigned)dump_error_example[0] >> 24);
-
- #define FIRST ((char*) &first_data) /* first symbol in data hunk */
-
- for(is = start; (char *)is < (char *)end; is++)
- {
- ip = (unsigned int *) is;
- if((((*ip >> 24) == 0x08)
- || (*ip >> 24) == de)
- && ! check_ignore(ip))
- {
- if(lasthit+1 == ip)
- {
- lasthit++;
- range = 1;
- }
- else
- {
- if(range)
- {
- fprintf(stderr,"%s: 0x%08lx .. 0x%08lx (0x%08lx)\n",
- s,
- (char *)starthit-FIRST,
- (char *)lasthit-FIRST,
- (char*)lasthit-(char*)starthit);
- range = 0;
- }
- else
- {
- starthit = lasthit = ip;
- }
- }
- }
- else
- {
- if((unsigned short *) lasthit+1 != is)
- {
- if(range)
- {
- fprintf(stderr,"%s: 0x%08lx .. 0x%08lx (0x%08lx)\n",
- s,
- (char *)starthit-FIRST,
- (char *)lasthit-FIRST,
- (char*)lasthit-(char*)starthit);
- }
- else if(lasthit)
- {
- fprintf(stderr,"%s: 0x%08lx (0x%08lx)\n", s, (char *)lasthit-FIRST, *lasthit);
- }
- range = 0;
- lasthit = NULL;
- }
- }
-
- }
- if(range)
- {
- fprintf(stderr,"%s: 0x%08lx .. 0x%08lx (0x%08lx)\n",
- s,
- (char *)starthit-FIRST,
- (char *)lasthit-FIRST,
- (char*)lasthit-(char*)starthit);
- }
- else if(lasthit)
- {
- fprintf(stderr,"%s: 0x%08lx\n (0x%08ls)", s, (char *)lasthit-FIRST, *lasthit);
- }
- }
-
- void
- check_cands(void)
- {
- fprintf(stderr,"Possible candidates for FAR or amiga_dump\n");
- check_cand("DATA", &first_data, &last_data);
- check_cand("BSS ", &first_bss, &last_bss);
- }
-
-
- #ifdef DBUG
- static int mcol = 0;
- static int mrow = 0;
- static FILE *mfile;
- static char spaces[] = " ";
- static mtresh = 0;
- void MInit(char *s)
- {
- mcol = 0;
- mrow = 0;
- mtresh = 0;
- mfile = fopen(s,"a");
- fprintf(mfile,"\n***START***\n");
- }
- void MClean()
- {
- fprintf(mfile,"\n**END**\n");
- fclose(mfile);
- }
- #define P(x)
- void MEnter(char *s)
- {
- if(mtresh > 100) return;
- #if 0
- fwrite(spaces, mcol, 1, mfile);
- #endif
- fprintf(mfile, "(%d) %s\n", mcol, s);
- mcol += 1;
- }
- void M(char *s)
- {
- if(mtresh > 100) return;
- mtresh++;
- #if 0
- if(mcol)
- fwrite(spaces, mcol, 1, mfile);
- #endif
- fprintf(mfile, "(%d) %s\n", mcol, s);
- }
- void MLeave(char *s)
- {
- if(mtresh > 100) return;
-
- mcol -= 1;
- #if 0
- if(mcol)
- fwrite(spaces, mcol, 1, mfile);
- #endif
- fprintf(mfile, "(%d) %s\n", mcol, s);
- }
- #else
- #define MInit(x)
- #define MClean()
- #define MEnter(x)
- #define M(x)
- #define P(x)
- #define MLeave(x)
- #endif
-
- static void *hunk_pointer(void *ptr)
- {
- if (!ptr)
- {
- P("P0");
- return ptr;
- }
-
- #if 1 /* CHFIXME */
- if(RANGE(ptr, first_fn, last_fn) && ((char *)ptr - (char *)first_fn) == 0x21c)
- cpr();
- #endif
-
- if (RANGE(ptr, first_fn, last_fn))
- {
- P("PC");
- return (void *)(HUNK_CODE | (char *)ptr - (char *)first_fn);
- }
- else if (RANGE(ptr, &first_data, &last_data))
- {
- P("PD");
- return (void *)(HUNK_DATA | (char *)ptr - (char *)&first_data);
- }
- else if (RANGE(ptr, &first_bss, &last_bss))
- {
- P("PB");
- return (void *)(HUNK_BSS | (char *)ptr - (char *)&first_bss);
- }
- else if (RANGE(ptr, malloc_hunk, malloc_hunk + malloc_hunk_size))
- {
- P("PM");
- return (void *)(HUNK_MALLOC | (char *)ptr - malloc_hunk);
- }
- else if (RANGE(ptr, pure, (char *)pure + puresize))
- {
- P("PP");
- return (void *)(HUNK_PURE | (char *)ptr - (char *)pure);
- }
- else
- {
- _message("hunk_pointer: cannot locate pointer 0x%08lx", ptr);
- print_ranges();
- bailout(0);
- }
- }
-
- static Lisp_Object hunk_lispptr(Lisp_Object *objptr, Lisp_Object val)
- {
- int type = val & ~VALMASK;
- void *ptr = (void *)XPNTR(val);
-
- #if 1 /* CHFIXME */
- if(RANGE(ptr, first_fn, last_fn) && ((char *)ptr - (char *)first_fn) == 0x21c)
- cpr();
- #endif
-
- if (RANGE(ptr, first_fn, last_fn))
- {
- M("LC");
- return type | HUNK_CODE | (char *)ptr - (char *)first_fn;
- }
- else if (RANGE(ptr, &first_data, &last_data))
- {
- M("LD");
- return type | HUNK_DATA | (char *)ptr - (char *)&first_data;
- }
- else if (RANGE(ptr, &first_bss, &last_bss))
- {
- M("LB");
- return type | HUNK_BSS | (char *)ptr - (char *)&first_bss;
- }
- else if (RANGE(ptr, pure, (char *)pure + puresize))
- {
- M("LP");
- return type | HUNK_PURE | (char *)ptr - (char *)pure;
- }
- else if (RANGE(ptr, malloc_hunk, malloc_hunk + malloc_hunk_size))
- {
- M("LM");
- return type | HUNK_MALLOC | (char *)ptr - malloc_hunk;
- }
- else
- {
- _message("hunk_pointer: cannot locate pointer 0x%08lx", ptr);
- print_ranges();
- bailout(0);
- }
- }
-
- static void patch_pointers ();
-
- static void patch_buffer (buf)
- Lisp_Object buf;
- {
- Lisp_Object tem;
- register struct buffer *buffer = XBUFFER (buf);
- register Lisp_Object *ptr;
-
- buffer->text.beg = hunk_pointer (buffer->text.beg);
- patch_pointers (&buffer->markers);
-
- /* This is the buffer's markbit */
- patch_pointers (&buffer->name);
- assert(!XMARKBIT(&buffer->name)); /* CHFIXME */
- XMARK (buffer->name);
-
- for (ptr = &buffer->name + 1;
- (char *)ptr < (char *)buffer + sizeof (struct buffer);
- ptr++)
- patch_pointers (ptr);
- }
-
- static void patch_pointers (objptr)
- Lisp_Object *objptr;
- {
- register Lisp_Object obj;
-
- MEnter("O+");
- loop:
- obj = *objptr;
-
- loop2:
- XUNMARK (obj);
-
- switch (XGCTYPE (obj))
- {
- case Lisp_String:
- M("O1");
- /* CHIXME */
- {
- register struct Lisp_String *ptr = XSTRING (obj);
-
- if (ptr->size & MARKBIT)
- /* A large string. */
- _message("Lisp_String case: large_string found!");
- }
- *objptr = hunk_lispptr(objptr, *objptr);
- break;
-
- case Lisp_Vector:
- case Lisp_Window:
- case Lisp_Process:
- case Lisp_Window_Configuration:
- M("O2");
- *objptr = hunk_lispptr(objptr, *objptr);
- {
- register struct Lisp_Vector *ptr = XVECTOR (obj);
- register int size = ptr->size;
- struct Lisp_Vector *volatile ptr1 = ptr; /* CHFIXME */
- register int i;
-
- if (size & ARRAY_MARK_FLAG) break; /* Already marked */
- ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */
- for (i = 0; i < size; i++) /* and then mark its elements */
- patch_pointers (&ptr1->contents[i]);
- }
- break;
-
- case Lisp_Compiled: /* similar to vector but avoid some recursion */
- M("O3");
- *objptr = hunk_lispptr(objptr, *objptr);
- {
- register struct Lisp_Vector *ptr = XVECTOR (obj);
- register int size = ptr->size;
- struct Lisp_Vector *volatile ptr1 = ptr; /* CHFIXME */
- register int i;
-
- if (size & ARRAY_MARK_FLAG) break; /* Already marked */
- ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */
- for (i = 0; i < size; i++) /* and then mark its elements */
- if (i != COMPILED_CONSTANTS)
- patch_pointers (&ptr1->contents[i]);
- objptr = &ptr1->contents[COMPILED_CONSTANTS];
-
- goto loop;
- }
- break;
-
- case Lisp_Symbol:
- M("O4");
- *objptr = hunk_lispptr(objptr, *objptr);
- {
- register struct Lisp_Symbol * volatile ptr = XSYMBOL (obj);
- struct Lisp_Symbol *ptrx;
-
- if (XMARKBIT (ptr->plist)) break;
- XMARK (ptr->plist);
- patch_pointers ((Lisp_Object *) &ptr->value);
- patch_pointers (&ptr->function);
- patch_pointers (&ptr->plist);
- XSETTYPE (*(Lisp_Object *) &ptr->name, Lisp_String);
- patch_pointers ((Lisp_Object *) &ptr->name);
- objptr = (Lisp_Object *)&ptr->next;
- ptr = ptr->next;
- if (ptr)
- {
- ptrx = ptr; /* Use pf ptrx avoids compiler bug on Sun */
- XSETSYMBOL (obj, ptrx);
- /* We can't goto loop here because *objptr doesn't contain an
- actual Lisp_Object with valid datatype field. */
-
- goto loop2;
- }
- }
- break;
-
- case Lisp_Marker:
- M("O5");
- {
- struct Lisp_Marker *ptr = XMARKER (obj);
-
- *objptr = hunk_lispptr(objptr, *objptr);
- if (XMARKBIT (ptr->chain)) break;
- XMARK (ptr->chain);
- ptr->buffer = hunk_pointer (ptr->buffer);
- patch_pointers (&ptr->chain);
- break;
- }
-
- case Lisp_Cons:
- case Lisp_Buffer_Local_Value:
- case Lisp_Some_Buffer_Local_Value:
- M("O6");
- *objptr = hunk_lispptr(objptr, *objptr);
- {
- register struct Lisp_Cons *ptr = XCONS (obj);
- if (XMARKBIT (ptr->car)) break;
- XMARK (ptr->car);
- patch_pointers (&ptr->car);
- objptr = &XCONS (obj)->cdr;
- goto loop;
- }
-
- case Lisp_Buffer:
- M("O7");
- *objptr = hunk_lispptr(objptr, *objptr);
- if (!XMARKBIT (XBUFFER (obj)->name))
- patch_buffer (obj);
- break;
-
- case Lisp_Subr:
- M("O8");
- {
- struct Lisp_Subr *subr = XSUBR(obj);
-
- *objptr = hunk_lispptr(objptr, *objptr);
- if (subr->min_args & 0x8000) break;
- subr->min_args |= 0x8000;
- subr->function = hunk_pointer(subr->function);
- subr->symbol_name = hunk_pointer(subr->symbol_name);
- subr->prompt = hunk_pointer(subr->prompt);
- if ((long)subr->doc >= 0) /* Make sure that not a doc offset */
- subr->doc = hunk_pointer(subr->doc);
- break;
- }
-
- case Lisp_Int:
- case Lisp_Void:
- case Lisp_Buffer_Objfwd: break;
-
- case Lisp_Intfwd:
- case Lisp_Boolfwd:
- case Lisp_Objfwd:
- case Lisp_Internal_Stream:
- M("O9");
- *objptr = hunk_lispptr(objptr, *objptr);
- /* Don't bother with Lisp_Buffer_Objfwd,
- since all markable slots in current buffer marked anyway. */
- /* Don't need to do Lisp_Objfwd, since the places they point
- are protected with staticpro. */
- break;
-
- #ifdef LISP_FLOAT_TYPE
- case Lisp_Float:
- M("OA");
- *objptr = hunk_lispptr(objptr, *objptr);
- XMARK (XFLOAT (obj)->type);
- break;
- #endif /* LISP_FLOAT_TYPE */
-
- default:
- _message("patch_pointers: unknown XGCTYPE (obj): %ld", XGCTYPE (obj));
- abort ();
- }
- MLeave("O-");
- }
-
- static void patch_chain(void **ptr, int offset)
- {
- while (*ptr)
- {
- void **next = (void **)((char *)*ptr + offset);
-
- *ptr = hunk_pointer(*ptr);
- ptr = next;
- }
- }
-
- #define HUNK_LISPPTR(a) a = hunk_lispptr(&a,a)
- #define HUNK_PTR(a) a = hunk_pointer(a)
-
- static void patch(void)
- {
- Lisp_Object LO;
- int i;
- struct string_block *sptr;
- struct buffer *bptr;
- struct mem_header *mem;
- struct backtrace *backlist;
- struct catchtag *catch;
-
- MInit("MLOG.patch");
- print_ranges(); /* CHFIXME */
-
- #ifdef DBUG
- i = 0;
- #else
- for (i = 0; i < staticidx; i++)
- #endif
- {
- if (!XMARKBIT(*staticvec[i]))
- {
- patch_pointers(staticvec[i]);
- XMARK(*staticvec[i]);
- }
- staticvec[i] = hunk_pointer(staticvec[i]);
- }
- #ifndef DBUG
- /* Patch all the pointers normally used before a dump ! */
- patch_chain((void **)&cons_block, 0);
- patch_chain((void **)&cons_free_list, 0);
-
- patch_chain((void **)&all_vectors, 4);
-
- patch_chain((void **)&symbol_block, 0);
- patch_chain((void **)&symbol_free_list, 4);
-
- patch_chain((void **)&marker_block, 0);
- patch_chain((void **)&marker_free_list, 4);
-
- patch_chain((void **)&interval_block, 0);
- patch_chain((void **)&interval_free_list, 4*sizeof(long));
-
- /* Strings are lots of fun */
- patch_chain((void **)&large_string_blocks, 0);
- sptr = first_string_block;
- while (sptr)
- {
- struct string_block *next = sptr->next;
-
- if (sptr->next) HUNK_PTR(sptr->next);
- if (sptr->prev) HUNK_PTR(sptr->prev);
- sptr = next;
- }
- HUNK_PTR(first_string_block);
- HUNK_PTR(current_string_block);
-
- /* More fun with buffers */
- bptr = all_buffers;
- if (bptr)
- {
- while (bptr->next)
- {
- struct buffer *next = bptr->next;
-
- HUNK_PTR(bptr->next);
- bptr = next;
- }
- }
- HUNK_PTR(all_buffers);
- HUNK_PTR(current_buffer);
-
- #ifdef LISP_FLOAT_TYPE
- patch_chain((void **) &float_block, 0);
- patch_chain((void **) &float_free_list, 0);
- #endif /* LISP_FLOAT_TYPE */
-
- #if 0 /* CHFIXME needed ? */
- /* even more fun with 19.25 backtrace */
- for (backlist = backtrace_list; backlist; )
- {
- struct backtrace *next = backlist->next;
-
- if (!XMARKBIT (*backlist->function))
- {
- patch_pointers(backlist->function);
- XMARK (*backlist->function);
- }
- if (backlist->nargs == UNEVALLED || backlist->nargs == MANY)
- i = 0;
- else
- i = backlist->nargs - 1;
- for (; i >= 0; i--)
- if (!XMARKBIT (backlist->args[i]))
- {
- patch_pointers(&backlist->args[i]);
- XMARK (backlist->args[i]);
- }
- if(backlist->next) HUNK_PTR(backlist->next);
- backlist = next;
- }
- HUNK_PTR(backtrace_list);
-
- for (catch = catchlist; catch;)
- {
- struct catchtag *next = catch->next;
-
- patch_pointers (&catch->tag);
- patch_pointers (&catch->val);
- HUNK_PTR(catch->backlist);
- HUNK_PTR(catch->handlerlist);
-
- if(catch->next) HUNK_PTR(catch->next);
- catch = next;
- }
- HUNK_PTR(catchlist);
- #endif
-
- /* HUNK_PTR(gcprolist); CHFIXME*/
- HUNK_PTR(stack_copy);
-
- HUNK_PTR(kbd_macro_buffer);
- HUNK_PTR(minibuf_save_vector);
- HUNK_PTR(searchbuf.buffer);
- HUNK_PTR(searchbuf.fastmap);
- HUNK_PTR(specpdl);
- HUNK_PTR(read_buffer);
-
- #if 0 /* CHFIXME */
- MouseMap = hunk_lispptr(&MouseMap, MouseMap);
- #endif
- HUNK_LISPPTR( current_global_map );
- HUNK_LISPPTR( global_map );
- HUNK_LISPPTR( meta_map );
- HUNK_LISPPTR( control_x_map );
-
- HUNK_LISPPTR( selected_window );
-
- HUNK_LISPPTR( Qvariable_documentation );
-
- #ifndef MULTI_FRAME
- /* CHFIXME: use makro */
- HUNK_LISPPTR( the_only_frame.root_window );
- #else
- you lose;
- #endif
-
- mem = free_list;
- HUNK_PTR( free_list );
- while (mem)
- {
- struct mem_header *next = mem->next;
-
- HUNK_PTR( mem->prev );
- HUNK_PTR( mem->next );
- mem = next;
- }
-
- for (i = 0; i <= 4; i++)
- HUNK_PTR( callint_argfuns[i] );
-
- HUNK_PTR( fail_stack.stack );
- HUNK_PTR( regstart );
- HUNK_PTR( regend );
- HUNK_PTR( old_regstart );
- HUNK_PTR( old_regend );
- HUNK_PTR( best_regstart );
- HUNK_PTR( best_regend );
- HUNK_PTR( reg_info );
- HUNK_PTR( reg_dummy );
- HUNK_PTR( reg_info_dummy );
-
- for(i = 0; i < HEAD_TABLE_SIZE; i++)
- {
- HUNK_PTR( head_table[i].var );
- HUNK_PTR( head_table[i].name );
- HUNK_PTR( head_table[i].kind );
- }
- for(i = 0; i < SCROLL_BAR_PARTS_SIZE; i++)
- {
- HUNK_PTR( scroll_bar_parts[i] );
- }
- HUNK_PTR(kbd_fetch_ptr);
- HUNK_PTR(kbd_store_ptr);
- XSET(LO, Lisp_Buffer, &buffer_local_types);
- patch_buffer(LO);
-
- HUNK_LISPPTR(Qdirectory_files);
- HUNK_LISPPTR(Qfile_name_completion);
- HUNK_LISPPTR(Qfile_name_all_completions);
- HUNK_LISPPTR(Qfile_attributes);
- HUNK_LISPPTR(Qset_visited_file_modtime);
- /* HUNK_LISPPTR(stream_process);*/
-
- HUNK_PTR(message_text);
-
- /* search.c */
- HUNK_PTR(search_regs.start);
- HUNK_PTR(search_regs.end);
- #endif
- MClean();
- check_cands();
- }
-
- static dump(char *fn)
- {
- BPTR fd;
- long size;
-
- fd = Open(fn, MODE_NEWFILE);
- if (!fd)
- {
- static void unpatch(void);
-
- unpatch();
- _fail("emacs hasn't been dumped (%s missing)", fn);
- }
-
- Write(fd, (char *)&puresize, sizeof puresize);
- Write(fd, (char *)&malloc_hunk_size, sizeof malloc_hunk_size);
- Write(fd, (char *)&first_data, (char *)&last_data - (char *)&first_data);
- Write(fd, (char *)&first_bss, (char *)&last_bss - (char *)&first_bss);
- Write(fd, (char *)pure, puresize);
- Write(fd, (char *)malloc_hunk, malloc_hunk_size);
- Write(fd, (char *)&staticidx, sizeof staticidx);
- Write(fd, (char *)staticvec, staticidx * sizeof(Lisp_Object *));
- size = (char *)last_fn - (char *)first_fn;
- Write(fd, (char *)&size, sizeof size);
-
- Close(fd);
- }
-
- static void *make_pointer(void *ptr)
- {
- int hunk = (long)ptr & HUNK_MASK;
- int offset = (long)ptr & (VALMASK & ~HUNK_MASK);
-
- if (!ptr)
- {
- P("P0");
- return 0;
- }
-
- if (hunk == HUNK_CODE)
- {
- P("PC");
- return (char *)first_fn + offset;
- }
- if (hunk == HUNK_DATA)
- {
- P("PD");
- return (char *)&first_data + offset;
- }
- if (hunk == HUNK_BSS)
- {
- P("PB");
- return (char *)&first_bss + offset;
- }
- if (hunk == HUNK_PURE)
- {
- P("PP");
- return (char *)pure + offset;
- }
- if (hunk == HUNK_MALLOC)
- {
- P("PM");
- return malloc_hunk + offset;
- }
- assert(0);
- }
-
- static Lisp_Object make_lispptr(Lisp_Object *objptr, Lisp_Object obj)
- {
- long val = XUINT(obj);
- int hunk = val & HUNK_MASK;
- int offset = val & ~HUNK_MASK;
- char *ptr;
-
- assert(obj); /* CHFIXME */
- if (hunk == HUNK_CODE)
- {
- M("LC");
- ptr = (char *)first_fn + offset;
- }
- else if (hunk == HUNK_DATA)
- {
- M("LD");
- ptr = (char *)&first_data + offset;
- }
- else if (hunk == HUNK_BSS)
- {
- M("LB");
- ptr = (char *)&first_bss + offset;
- }
- else if (hunk == HUNK_PURE)
- {
- M("LP");
- ptr = (char *)pure + offset;
- }
- else if (hunk == HUNK_MALLOC)
- {
- M("LM");
- ptr = malloc_hunk + offset;
- }
- else assert(0);
-
- assert((int) ptr > 0); /* CHFIXME */
- OXSETPNTR(obj, (long)ptr); /* CHFIXME */
- return obj;
- }
-
- static void unpatch_pointers ();
-
- static void unpatch_buffer (buf)
- Lisp_Object buf;
- {
- Lisp_Object tem;
- register struct buffer *buffer = XBUFFER (buf);
- register Lisp_Object *ptr;
-
- buffer->text.beg = make_pointer (buffer->text.beg);
- unpatch_pointers (&buffer->markers);
-
- /* This is the buffer's markbit */
- XUNMARK (buffer->name);
- unpatch_pointers (&buffer->name);
-
- for (ptr = &buffer->name + 1;
- (char *)ptr < (char *)buffer + sizeof (struct buffer);
- ptr++)
- unpatch_pointers (ptr);
- }
-
- static void unpatch_pointers (objptr)
- Lisp_Object *objptr;
- {
- register Lisp_Object obj;
- Lisp_Object obj2;
-
- MEnter("O+");
- loop:
- obj = *objptr;
-
- loop2:
- XUNMARK (obj);
-
- switch (XGCTYPE (obj))
- {
- case Lisp_String:
- M("O1");
- *objptr = make_lispptr(objptr, *objptr);
- break;
-
- case Lisp_Vector:
- case Lisp_Window:
- case Lisp_Process:
- case Lisp_Window_Configuration:
- M("O2");
- obj = *objptr = make_lispptr(objptr, *objptr);
- {
- register struct Lisp_Vector *ptr = XVECTOR (obj);
- register int size;
- struct Lisp_Vector *volatile ptr1 = ptr; /* CHFIXME */
- register int i;
-
- if (!(ptr->size & ARRAY_MARK_FLAG)) break; /* Already unmarked */
- size = ptr->size &= ~ARRAY_MARK_FLAG; /* Else unmark it */
- for (i = 0; i < size; i++) /* and then unmark its elements */
- unpatch_pointers (&ptr1->contents[i]);
- }
- break;
-
- case Lisp_Compiled: /* similar to vector but avoid some recursion */
- M("O3");
- obj = *objptr = make_lispptr(objptr, *objptr);
- {
- register struct Lisp_Vector *ptr = XVECTOR (obj);
- register int size = ptr->size;
- struct Lisp_Vector *volatile ptr1 = ptr; /* CHFIXME */
- register int i;
-
- if (!(size & ARRAY_MARK_FLAG)) break; /* Already unmarked */
- size = ptr->size &= ~ARRAY_MARK_FLAG; /* Else unmark it */
- for (i = 0; i < size; i++) /* and then mark its elements */
- if (i != COMPILED_CONSTANTS)
- unpatch_pointers (&ptr1->contents[i]);
- objptr = (Lisp_Object *) &ptr1->contents[COMPILED_CONSTANTS];
-
- goto loop;
- }
- break;
-
- case Lisp_Symbol:
- M("O4");
- /* due to goto below objptr may not point to object containing
- SYMBOL type information so let obj care for symbol type */
- obj2 = *objptr = make_lispptr(objptr, *objptr);
- {
- register struct Lisp_Symbol * volatile ptr = XSYMBOL (obj2);
- struct Lisp_Symbol *ptrx;
-
- if (!XMARKBIT (ptr->plist)) break;
- XUNMARK (ptr->plist);
- unpatch_pointers ((Lisp_Object *) &ptr->value);
- unpatch_pointers (&ptr->function);
- unpatch_pointers (&ptr->plist);
- unpatch_pointers ((Lisp_Object *) &ptr->name);
- ptr->name = XSTRING (*(Lisp_Object *)&ptr->name);
- objptr = (Lisp_Object *)&ptr->next;
- ptr = ptr->next;
- if (ptr)
- {
- ptrx = ptr; /* Use pf ptrx avoids compiler bug on Sun */
- XSETSYMBOL (obj, ptrx);
-
- /* We can't goto loop here because *objptr doesn't contain an
- actual Lisp_Object with valid datatype field. */
-
- goto loop2;
- }
- }
- break;
-
- case Lisp_Marker:
- M("O5");
- obj = *objptr = make_lispptr(objptr, *objptr);
- {
- struct Lisp_Marker *ptr = XMARKER (obj);
-
- if (!XMARKBIT (ptr->chain)) break;
- XUNMARK (ptr->chain);
- ptr->buffer = make_pointer (ptr->buffer);
- unpatch_pointers (&ptr->chain);
- }
- break;
-
- case Lisp_Cons:
- case Lisp_Buffer_Local_Value:
- case Lisp_Some_Buffer_Local_Value:
- M("O6");
- obj = *objptr = make_lispptr(objptr, *objptr);
- {
- register struct Lisp_Cons *ptr = XCONS (obj);
- if (!XMARKBIT (ptr->car)) break;
- XUNMARK (ptr->car);
- unpatch_pointers (&ptr->car);
- objptr = &ptr->cdr;
-
- goto loop;
- }
-
- case Lisp_Buffer:
- M("O7");
- obj = *objptr = make_lispptr(objptr, *objptr);
- if (XMARKBIT (XBUFFER (obj)->name))
- unpatch_buffer (obj);
- break;
-
- case Lisp_Subr:
- M("O8");
- obj = *objptr = make_lispptr(objptr, *objptr);
- {
- struct Lisp_Subr *subr = XSUBR(obj);
-
- if (!(subr->min_args & 0x8000)) break;
- subr->min_args &= ~0x8000;
- subr->function = make_pointer(subr->function);
- subr->symbol_name = make_pointer(subr->symbol_name);
- subr->prompt = make_pointer(subr->prompt);
- if ((long)subr->doc >= 0) /* Make sure that not a doc offset */
- subr->doc = make_pointer(subr->doc);
- break;
- }
-
- case Lisp_Int:
- case Lisp_Void:
- case Lisp_Buffer_Objfwd: break;
-
- case Lisp_Intfwd:
- case Lisp_Boolfwd:
- case Lisp_Objfwd:
- case Lisp_Internal_Stream:
- M("O9");
- *objptr = make_lispptr(objptr, *objptr);
- /* Don't bother with Lisp_Buffer_Objfwd,
- since all markable slots in current buffer marked anyway. */
- /* Don't need to do Lisp_Objfwd, since the places they point
- are protected with staticpro. */
- break;
-
- #ifdef LISP_FLOAT_TYPE
- case Lisp_Float:
- M("OA");
- obj = *objptr = make_lispptr(objptr, *objptr);
- XUNMARK (XFLOAT (obj)->type);
- break;
- #endif /* LISP_FLOAT_TYPE */
-
- default:
- abort ();
- }
- MLeave("O-");
- }
-
- static void unpatch_chain(void **ptr, int offset)
- {
- while (*ptr)
- {
- *ptr = make_pointer(*ptr);
- ptr = (void **)((char *)*ptr + offset);
- }
- }
-
- /* CHFIXME: for all! */
- #define MAKE_LISPPTR(a) a = make_lispptr(&a,a)
- #define MAKE_PTR(a) a = make_pointer(a)
-
- /* Reconstructs the addresses that were patched */
- static void unpatch(void)
- {
- Lisp_Object LO;
- int fd, i;
- struct string_block *sptr;
- struct buffer *bptr;
- struct mem_header *mem;
- struct backtrace *backlist;
- struct catchtag *catch;
-
- print_ranges(); /* CHFIXME */
-
- MInit("MLOG.unpatch");
- #ifdef DBUG
- i = 0;
- #else
- for (i = 0; i < staticidx; i++)
- #endif
- {
- staticvec[i] = make_pointer(staticvec[i]);
- if (XMARKBIT(*staticvec[i]))
- {
- XUNMARK(*staticvec[i]);
- unpatch_pointers(staticvec[i]);
- }
- }
-
- #ifndef DBUG
- /* Unpatch all the pointers normally used before a dump ! */
- unpatch_chain((void **)&cons_block, 0);
- unpatch_chain((void **)&cons_free_list, 0);
-
- unpatch_chain((void **)&all_vectors, 4);
-
- unpatch_chain((void **)&symbol_block, 0);
- unpatch_chain((void **)&symbol_free_list, 4);
-
- unpatch_chain((void **)&marker_block, 0);
- unpatch_chain((void **)&marker_free_list, 4);
-
- unpatch_chain((void **)&interval_block, 0);
- unpatch_chain((void **)&interval_free_list, 4*sizeof(long));
-
- /* Strings are lots of fun */
- unpatch_chain((void **)&large_string_blocks, 0);
- sptr = MAKE_PTR(first_string_block);
- MAKE_PTR(current_string_block);
- while (sptr)
- {
- if (sptr->next) MAKE_PTR(sptr->next);
- if (sptr->prev) MAKE_PTR(sptr->prev);
- sptr = sptr->next;
- }
-
- /* More fun with buffers */
- bptr = MAKE_PTR(all_buffers);
- if (bptr)
- {
- while (bptr->next)
- {
- MAKE_PTR(bptr->next);
- bptr = bptr->next;
- }
- }
- MAKE_PTR(current_buffer);
-
- #ifdef LISP_FLOAT_TYPE
- unpatch_chain((void **) &float_block, 0);
- unpatch_chain((void **) &float_free_list, 0);
- #endif /* LISP_FLOAT_TYPE */
-
- #if 0 /* CHFIXME needed ? */
- /* even more fun with 19.25 backtrace */
- MAKE_PTR(backtrace_list);
- for (backlist = backtrace_list; backlist; backlist = backlist->next)
- {
- if(backlist->next) MAKE_PTR(backlist->next);
-
- if (XMARKBIT (*backlist->function))
- {
- XUNMARK (*backlist->function);
- unpatch_pointers(backlist->function);
- }
- if (backlist->nargs == UNEVALLED || backlist->nargs == MANY)
- i = 0;
- else
- i = backlist->nargs - 1;
- for (; i >= 0; i--)
- if (XMARKBIT (backlist->args[i]))
- {
- XUNMARK (backlist->args[i]);
- unpatch_pointers(&backlist->args[i]);
- }
- }
-
- MAKE_PTR(catchlist);
- for (catch = catchlist; catch; catch = catch->next)
- {
- if(catch->next) MAKE_PTR(catch->next);
-
- unpatch_pointers (&catch->tag);
- unpatch_pointers (&catch->val);
- MAKE_PTR(catch->backlist);
- MAKE_PTR(catch->handlerlist);
- }
- #endif
-
- /* MAKE_PTR(gcprolist); CHFIXME */
- MAKE_PTR(stack_copy);
-
- MAKE_PTR(kbd_macro_buffer);
- MAKE_PTR(minibuf_save_vector);
- MAKE_PTR(searchbuf.buffer);
- MAKE_PTR(searchbuf.fastmap);
- MAKE_PTR(specpdl);
- MAKE_PTR(read_buffer);
-
- #if 0 /* CHFIXME */
- MouseMap = make_lispptr(&MouseMap, MouseMap);
- #endif
- MAKE_LISPPTR(current_global_map);
- MAKE_LISPPTR(global_map);
- MAKE_LISPPTR(meta_map);
- MAKE_LISPPTR(control_x_map);
-
- MAKE_LISPPTR(selected_window);
-
- MAKE_LISPPTR(Qvariable_documentation);
-
- #ifndef MULTI_FRAME
- /* CHFIXME: use makro */
- MAKE_LISPPTR(the_only_frame.root_window);
- #else
- you lose;
- #endif
-
- MAKE_PTR(free_list);
- mem = free_list;
- while (mem)
- {
- MAKE_PTR(mem->prev);
- MAKE_PTR(mem->next);
- mem = mem->next;
- }
-
- for (i = 0; i <= 4; i++)
- MAKE_PTR(callint_argfuns[i]);
-
- MAKE_PTR(fail_stack.stack);
- MAKE_PTR(regstart);
- MAKE_PTR(regend);
- MAKE_PTR(old_regstart);
- MAKE_PTR(old_regend);
- MAKE_PTR(best_regstart);
- MAKE_PTR(best_regend);
- MAKE_PTR(reg_info);
- MAKE_PTR(reg_dummy);
- MAKE_PTR(reg_info_dummy);
-
- for(i = 0; i < HEAD_TABLE_SIZE; i++)
- {
- MAKE_PTR(head_table[i].var);
- MAKE_PTR(head_table[i].name);
- MAKE_PTR(head_table[i].kind);
- }
- for(i = 0; i < SCROLL_BAR_PARTS_SIZE; i++)
- MAKE_PTR(scroll_bar_parts[i]);
-
- MAKE_PTR(kbd_fetch_ptr);
- MAKE_PTR(kbd_store_ptr);
-
- XSET(LO, Lisp_Buffer, &buffer_local_types);
- unpatch_buffer(LO);
-
- MAKE_LISPPTR(Qdirectory_files);
- MAKE_LISPPTR(Qfile_name_completion);
- MAKE_LISPPTR(Qfile_name_all_completions);
- MAKE_LISPPTR(Qfile_attributes);
- MAKE_LISPPTR(Qset_visited_file_modtime);
- /* MAKE_LISPPTR(stream_process);*/
-
- MAKE_PTR(message_text);
-
- /* search.c */
- MAKE_PTR(search_regs.start);
- MAKE_PTR(search_regs.end);
- #endif
- MClean();
- }
-
- static undump(char *fn)
- {
- BPTR fd;
- long code_size;
- char *_malloc_hunk;
- int *_pure;
- /*extern struct Library *FifoBase;
- struct Library *_FifoBase = FifoBase;*/
-
- fd = Open(fn, MODE_OLDFILE);
- if (!fd) return 0;
-
- Read(fd, (char *)&puresize, sizeof puresize);
- Read(fd, (char *)&malloc_hunk_size, sizeof malloc_hunk_size);
- _pure = dump_malloc(puresize);
- _malloc_hunk = dump_malloc(malloc_hunk_size + pre_alloc);
- Read(fd, (char *)&first_data, (char *)&last_data - (char *)&first_data);
- Read(fd, (char *)&first_bss, (char *)&last_bss - (char *)&first_bss);
- Read(fd, (char *)_pure, puresize);
- Read(fd, (char *)_malloc_hunk, malloc_hunk_size);
- Read(fd, (char *)&staticidx, sizeof staticidx);
- Read(fd, (char *)staticvec, staticidx * sizeof(Lisp_Object *));
- /*FifoBase = _FifoBase;*/
- if (Read(fd, (char *)&code_size, sizeof code_size) != sizeof code_size ||
- code_size != (char *)last_fn - (char *)first_fn)
- {
- Close(fd);
- bailout(fn);
- }
-
- Close(fd);
- malloc_hunk = _malloc_hunk;
- pure = _pure;
- return 1;
- }
-
- void map_out_data(char *fn)
- {
- if (amiga_initialized) error("You can only dump once !");
- Fgarbage_collect();
-
- #if 0 /* CHFIXME */
- dump("EMACS-DATA.pre");
- #endif
- patch();
- dump(fn);
- unpatch();
- #if 0
- dump("EMACS-DATA.post");
- #endif
- amiga_initialized = 1;
- }
-
- #ifndef MULTI_FRAME
- static struct x_display A_Display;
- #else
- you lose */
- #endif
-
- void map_in_data(int load)
- {
- if (load && undump(NAME_DATA))
- {
- unpatch();
- #if 0 /*CHFIXME */
- current_screen = new_screen = temp_screen = 0;
- message_buf = 0;
- #endif
- chars_wasted = 0;
- copybuf = 0;
- initialized = amiga_initialized = 1;
-
- /* CHFIXME: force errors if used but not patched */
- handlerlist = (void *) -1;
- catchlist = (void *)-1;
- backtrace_list = (void *)-1;
- #if 0
- FRAME_EXTERNAL_MENU_BAR(selected_frame) = 1; /* CHFIXME where to put? */
- #endif
- }
- else
- {
- malloc_hunk = dump_malloc(malloc_hunk_size + pre_alloc);
- pure = dump_malloc(puresize);
- }
- #ifndef MULTI_FRAME
- FRAME_DISPLAY(selected_frame) = &A_Display;
- #else
- you lose again.
- #endif
- amiga_undump_reinit();
- }
-
- void
- early_init_amiga_dump()
- {
- #ifndef MULTI_FRAME
- FRAME_DISPLAY(selected_frame) = &A_Display;
- #else
- you lose again.
- #endif
- }
-